package com.honghe.system.controller;

import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.honghe.common.annotation.Log;
import com.honghe.common.core.controller.BaseController;
import com.honghe.common.core.domain.AjaxResult;
import com.honghe.common.enums.BusinessType;
import com.honghe.system.domain.ContractInfo;
import com.honghe.system.service.IContractInfoService;
import com.honghe.common.utils.poi.ExcelUtil;
import com.honghe.common.core.page.TableDataInfo;
import org.apache.commons.lang3.StringUtils;
import com.honghe.common.utils.file.FileUtils;
import com.honghe.common.config.RuoYiConfig;
import java.io.File;
import com.honghe.common.constant.Constants;
import org.springframework.http.MediaType;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;

/**
 * 合同信息Controller
 * 
 * @author honghe
 * @date 2025-05-09
 */
@RestController
@RequestMapping("/system/info")
public class ContractInfoController extends BaseController
{
    @Autowired
    private IContractInfoService contractInfoService;

    /**
     * 查询合同信息列表
     */
    @PreAuthorize("@ss.hasPermi('system:info:list')")
    @GetMapping("/list")
    public TableDataInfo list(ContractInfo contractInfo)
    {
        startPage();
        List<ContractInfo> list = contractInfoService.selectContractInfoList(contractInfo);
        return getDataTable(list);
    }

    /**
     * 导出合同信息列表
     */
    @PreAuthorize("@ss.hasPermi('system:info:export')")
    @Log(title = "合同信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ContractInfo contractInfo)
    {
        List<ContractInfo> list = contractInfoService.selectContractInfoList(contractInfo);
        ExcelUtil<ContractInfo> util = new ExcelUtil<ContractInfo>(ContractInfo.class);
        util.exportExcel(response, list, "合同信息数据");
    }

    /**
     * 获取合同信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:info:query')")
    @GetMapping(value = "/{contractId}")
    public AjaxResult getInfo(@PathVariable("contractId") String contractId)
    {
        return success(contractInfoService.selectContractInfoByContractId(contractId));
    }

    /**
     * 新增合同信息
     */
    @PreAuthorize("@ss.hasPermi('system:info:add')")
    @Log(title = "合同信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ContractInfo contractInfo)
    {
        return toAjax(contractInfoService.insertContractInfo(contractInfo));
    }

    /**
     * 修改合同信息
     */
    @PreAuthorize("@ss.hasPermi('system:info:edit')")
    @Log(title = "合同信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ContractInfo contractInfo)
    {
        return toAjax(contractInfoService.updateContractInfo(contractInfo));
    }

    /**
     * 删除合同信息
     */
    @PreAuthorize("@ss.hasPermi('system:info:remove')")
    @Log(title = "合同信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{contractIds}")
    public AjaxResult remove(@PathVariable String[] contractIds)
    {
        return toAjax(contractInfoService.deleteContractInfoByContractIds(contractIds));
    }
    
    /**
     * 下载合同文件
     */
    @PreAuthorize("@ss.hasPermi('system:info:download')")
    @Log(title = "合同文件下载", businessType = BusinessType.OTHER)
    @GetMapping("/download/{contractId}")
    public AjaxResult download(@PathVariable("contractId") String contractId)
    {
        ContractInfo contractInfo = contractInfoService.selectContractInfoByContractId(contractId);
        if (contractInfo != null && StringUtils.isNotEmpty(contractInfo.getFileInfo())) {
            String fileInfo = contractInfo.getFileInfo();
            
            // 构建返回的URL，让前端直接访问通用下载控制器
            // 文件信息格式可能是：原始文件名|存储路径
            if (fileInfo.contains("|")) {
                String[] parts = fileInfo.split("\\|");
                if (parts.length >= 2) {
                    String filePath = parts[1];
                    
                    // 构建下载URL，跳转到通用下载控制器
                    return AjaxResult.success("获取文件路径成功", filePath);
                }
            }
            
            // 如果fileInfo就是文件路径，则直接返回
            return AjaxResult.success("获取文件路径成功", fileInfo);
        }
        
        return AjaxResult.error("未找到文件信息");
    }
    
    /**
     * 直接下载文件（处理实际的文件下载）
     */
    @PreAuthorize("@ss.hasPermi('system:info:download')")
    @Log(title = "合同文件直接下载", businessType = BusinessType.OTHER)
    @PostMapping("/downloadFile")
    public void downloadFile(String filePath, HttpServletResponse response) throws Exception
    {
        if (StringUtils.isEmpty(filePath)) {
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("文件路径为空");
            return;
        }
        
        logger.info("下载文件路径: {}", filePath);
        
        try {
            // 处理不同格式的路径
            String realFilePath = "";
            String fileName = "";
            boolean fileFound = false;
            
            // 处理上传时生成的格式: 原始文件名|存储路径
            if (filePath.contains("|")) {
                String[] parts = filePath.split("\\|");
                if (parts.length >= 2) {
                    String originalName = parts[0];
                    String storagePath = parts[1]; // 这是相对路径，如 2025/05/09/20250509165208_084f003c4b5a4c8c864642b81b5136c3.doc
                    
                    logger.info("解析到原始文件名: {}, 存储路径: {}", originalName, storagePath);
                    
                    // 构建多种可能的完整路径并尝试
                    List<String> possiblePaths = new ArrayList<>();
                    
                    // 1. 基于RuoYiConfig配置的路径
                    possiblePaths.add(RuoYiConfig.getProfile() + "/" + storagePath);
                    possiblePaths.add(RuoYiConfig.getProfile() + "/upload/" + storagePath);
                    possiblePaths.add(RuoYiConfig.getProfile() + "/cases/" + storagePath);
                    
                    // 2. 硬编码常见路径
                    possiblePaths.add("D:/ruoyi/uploadPath/" + storagePath);
                    possiblePaths.add("D:/ruoyi/uploadPath/upload/" + storagePath);
                    possiblePaths.add("D:/ruoyi/uploadPath/cases/" + storagePath);
                    
                    // 3. 如果路径已包含日期结构，可能是完整路径
                    if (!storagePath.startsWith("/") && !storagePath.startsWith("\\")) {
                        if (storagePath.matches("\\d{4}/\\d{2}/\\d{2}/.*")) {
                            possiblePaths.add(RuoYiConfig.getProfile() + "/" + storagePath);
                            possiblePaths.add("D:/ruoyi/uploadPath/" + storagePath);
                        }
                    }
                    
                    logger.info("将尝试以下路径: {}", possiblePaths);
                    
                    // 尝试所有可能的路径
                    for (String path : possiblePaths) {
                        File file = new File(path);
                        logger.info("尝试路径: {}, 文件存在: {}, 是文件: {}, 文件大小: {}字节", 
                            path, file.exists(), file.isFile(), file.exists() ? file.length() : 0);
                        
                        if (file.exists() && file.isFile() && file.length() > 0) {
                            realFilePath = path;
                            fileName = originalName; // 使用原始文件名作为下载文件名
                            fileFound = true;
                            logger.info("找到有效文件: {}, 大小: {}字节", realFilePath, file.length());
                            break;
                        }
                    }
                }
            }
            
            // 如果不是 original|path 格式或未找到文件，尝试其他格式
            if (!fileFound) {
                logger.info("未能通过原始文件名|存储路径格式找到文件，尝试其他格式");
                
                // 1. 检查是否需要特殊处理日期目录格式的文件
                if (filePath.matches("\\d{8}_[a-zA-Z0-9]+\\.\\w+")) {
                    // 格式类似于: 20250509164409_605d1fddc9c6449b86b9b5c0e66e9017.doc
                    logger.info("检测到文件名格式为时间戳_UUID类型");
                    
                    // 尝试解析日期
                    String dateStr = filePath.substring(0, 8);
                    String year = dateStr.substring(0, 4);
                    String month = dateStr.substring(4, 6);
                    String day = dateStr.substring(6, 8);
                    logger.info("从文件名解析日期: 年={}, 月={}, 日={}", year, month, day);
                    
                    // 尝试各种可能的路径
                    List<String> possiblePaths = new ArrayList<>();
                    possiblePaths.add(RuoYiConfig.getProfile() + "/upload/" + year + "/" + month + "/" + day + "/" + filePath);
                    possiblePaths.add(RuoYiConfig.getProfile() + "/upload/" + filePath);
                    possiblePaths.add(RuoYiConfig.getProfile() + "/cases/" + year + "/" + month + "/" + day + "/" + filePath);
                    possiblePaths.add(RuoYiConfig.getProfile() + "/cases/" + filePath);
                    possiblePaths.add("D:/ruoyi/uploadPath/" + year + "/" + month + "/" + day + "/" + filePath);
                    possiblePaths.add("D:/ruoyi/uploadPath/" + filePath);
                    possiblePaths.add("D:/ruoyi/uploadPath/upload/" + year + "/" + month + "/" + day + "/" + filePath);
                    possiblePaths.add("D:/ruoyi/uploadPath/upload/" + filePath);
                    possiblePaths.add("D:/ruoyi/uploadPath/cases/" + year + "/" + month + "/" + day + "/" + filePath);
                    possiblePaths.add("D:/ruoyi/uploadPath/cases/" + filePath);
                    
                    logger.info("将尝试以下路径: {}", possiblePaths);
                    
                    // 检查文件是否存在于可能的路径中
                    for (String path : possiblePaths) {
                        File file = new File(path);
                        logger.info("尝试路径: {}, 文件存在: {}, 是文件: {}, 文件大小: {}字节", 
                            path, file.exists(), file.isFile(), file.exists() ? file.length() : 0);
                        
                        if (file.exists() && file.isFile() && file.length() > 0) {
                            realFilePath = path;
                            fileName = file.getName();
                            fileFound = true;
                            logger.info("找到有效文件: {}, 大小: {}字节", realFilePath, file.length());
                            break;
                        }
                    }
                } 
                // 2. 如果是相对路径（以/开头）
                else if (filePath.startsWith("/")) {
                    logger.info("检测到相对路径格式");
                    
                    // 尝试多个基础路径
                    List<String> possiblePaths = new ArrayList<>();
                    possiblePaths.add(RuoYiConfig.getProfile() + StringUtils.substringAfter(filePath, Constants.RESOURCE_PREFIX));
                    possiblePaths.add(RuoYiConfig.getProfile() + filePath);
                    possiblePaths.add("D:/ruoyi/uploadPath" + StringUtils.substringAfter(filePath, Constants.RESOURCE_PREFIX));
                    possiblePaths.add("D:/ruoyi/uploadPath" + filePath);
                    
                    logger.info("将尝试以下路径: {}", possiblePaths);
                    
                    for (String path : possiblePaths) {
                        File file = new File(path);
                        logger.info("尝试路径: {}, 文件存在: {}, 是文件: {}, 文件大小: {}字节", 
                            path, file.exists(), file.isFile(), file.exists() ? file.length() : 0);
                        
                        if (file.exists() && file.isFile() && file.length() > 0) {
                            realFilePath = path;
                            fileName = StringUtils.substringAfterLast(filePath, "/");
                            fileFound = true;
                            logger.info("找到有效文件: {}, 大小: {}字节", realFilePath, file.length());
                            break;
                        }
                    }
                } 
                // 3. 如果是直接的文件路径
                else {
                    logger.info("检测到直接文件路径格式");
                    File file = new File(filePath);
                    logger.info("尝试直接路径: {}, 文件存在: {}, 是文件: {}, 文件大小: {}字节", 
                        filePath, file.exists(), file.isFile(), file.exists() ? file.length() : 0);
                    
                    if (file.exists() && file.isFile() && file.length() > 0) {
                        realFilePath = filePath;
                        fileName = StringUtils.substringAfterLast(filePath, "/");
                        if (StringUtils.isEmpty(fileName)) {
                            fileName = StringUtils.substringAfterLast(filePath, "\\");
                        }
                        if (StringUtils.isEmpty(fileName)) {
                            fileName = filePath;
                        }
                        fileFound = true;
                        logger.info("找到有效文件: {}, 大小: {}字节", realFilePath, file.length());
                    }
                }
            }
            
            // 如果没找到文件，尝试系统的通用下载路径
            if (!fileFound) {
                logger.info("尝试通用下载路径");
                String downloadPath = RuoYiConfig.getDownloadPath() + filePath;
                File downloadFile = new File(downloadPath);
                logger.info("尝试通用下载路径: {}, 文件存在: {}, 是文件: {}, 文件大小: {}字节", 
                    downloadPath, downloadFile.exists(), downloadFile.isFile(), downloadFile.exists() ? downloadFile.length() : 0);
                
                if (downloadFile.exists() && downloadFile.isFile() && downloadFile.length() > 0) {
                    realFilePath = downloadPath;
                    fileName = downloadFile.getName();
                    fileFound = true;
                    logger.info("在通用下载路径找到文件: {}, 大小: {}字节", realFilePath, downloadFile.length());
                }
            }
            
            // 检查文件是否存在
            if (!fileFound || StringUtils.isEmpty(realFilePath)) {
                logger.error("未能找到有效文件，原始路径: {}", filePath);
                response.setContentType("text/html;charset=utf-8");
                response.getWriter().write("文件不存在或已被删除");
                return;
            }
            
            File file = new File(realFilePath);
            logger.info("最终使用文件: {}, 下载名称: {}, 文件大小: {}字节", realFilePath, fileName, file.length());
            
            // 设置响应头信息
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, fileName);
            
            // 打开文件并写入输出流
            try (FileInputStream fis = new FileInputStream(file)) {
                byte[] buffer = new byte[1024];
                int bytesRead;
                long totalBytes = 0;
                
                // 手动读取文件并写入响应
                while ((bytesRead = fis.read(buffer)) != -1) {
                    response.getOutputStream().write(buffer, 0, bytesRead);
                    totalBytes += bytesRead;
                }
                
                response.getOutputStream().flush();
                logger.info("文件下载成功: {}, 总共写入: {}字节", realFilePath, totalBytes);
            } catch (IOException e) {
                logger.error("读取或写入文件流失败: {}", e.getMessage(), e);
                throw e;
            }
        } catch (Exception e) {
            logger.error("下载文件失败: {}", e.getMessage(), e);
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("下载文件失败: " + e.getMessage());
        }
    }
}
